import processing.core.*; 
import processing.xml.*; 

import controlP5.*; 
import java.util.ArrayList; 

import org.apache.xerces.impl.io.*; 
import org.apache.xerces.dom.*; 
import org.apache.xerces.dom3.as.*; 
import org.apache.xerces.impl.dv.util.*; 
import org.apache.xerces.impl.dv.dtd.*; 
import org.apache.xerces.xni.*; 
import org.apache.xerces.impl.xs.*; 
import org.apache.xerces.xinclude.*; 
import org.w3c.dom.ls.*; 
import org.apache.xerces.impl.xpath.regex.*; 
import org.apache.xerces.impl.dtd.*; 
import org.apache.xerces.dom.events.*; 
import org.apache.xerces.impl.xs.traversers.*; 
import org.apache.xerces.impl.*; 
import org.apache.xerces.impl.xs.psvi.*; 
import org.apache.wml.*; 
import org.apache.xml.serialize.*; 
import org.w3c.dom.html.*; 
import org.apache.xerces.jaxp.*; 
import org.apache.xerces.impl.xs.util.*; 
import org.apache.xerces.impl.msg.*; 
import org.apache.html.dom.*; 
import org.apache.xerces.impl.dv.*; 
import org.apache.wml.dom.*; 
import org.apache.xerces.impl.xpath.*; 
import org.apache.xerces.dom3.*; 
import org.apache.xerces.xni.grammars.*; 
import org.apache.xerces.impl.validation.*; 
import org.apache.xerces.impl.xs.identity.*; 
import org.apache.xerces.util.*; 
import org.apache.xerces.xni.psvi.*; 
import org.apache.xerces.xni.parser.*; 
import org.apache.xerces.dom3.bootstrap.*; 
import org.apache.xerces.impl.dtd.models.*; 
import org.apache.xerces.impl.xs.models.*; 
import org.apache.xerces.impl.dv.xs.*; 
import org.apache.xerces.parsers.*; 
import org.apache.xerces.impl.xs.opti.*; 

import java.applet.*; 
import java.awt.Dimension; 
import java.awt.Frame; 
import java.awt.event.MouseEvent; 
import java.awt.event.KeyEvent; 
import java.awt.event.FocusEvent; 
import java.awt.Image; 
import java.io.*; 
import java.net.*; 
import java.text.*; 
import java.util.*; 
import java.util.zip.*; 
import java.util.regex.*; 

public class Interficie extends PApplet {





Cargador car;
Slider slider;
Helper helper;
ControlP5 controlP5;
Explorador explorador;
boolean cargado=false;
int estado=0;
int x1=0;
int y1=0;
int etiqueta=-1;
int sliderValue=0;
ArrayList puntos= new ArrayList();
PImage b;
ControlGroup mBox;
ListBox l;
boolean msg=false;
boolean elim=false;
boolean modif=false;
boolean creando=false;
boolean mpress = true;

int resAncho=-1;
int resAlto=-1;
int resRadio=-1;
int nEt = 0;
float imgAncho=0;
float imgAlto=0;
float imgAncho2=0;
float imgAlto2=0;
private float zoom=1;
private float dragX=0;
private float dragY=0;
private float xd=0;
private float yd=0;
private float zm =0;
private float zoomy=1;
private PFont font;

private final String MSGIDLE = "Controls: MOUSE LEFT - Select  MOUSE RIGHT - Drag  MOUSE WEHEEL - Zoom";


Herramienta herActual;

PImage fondoEliminar;
PImage marco;
PImage opciones;

controlP5.Button eliminar,modificar;


public void setup() {
  size(1024,768);

  font = loadFont("ComicSansMS-Bold-48.vlw");
  
  
  b= loadImage("fondo.png");
 
  


  slider = new Slider();
  explorador = new Explorador(slider.getAlto());
  //explorador.cargarConf(this);
  helper = new Helper(250,explorador.getAncho(),slider.getAlto());
  helper.setVisible(false);
  helper.setText(MSGIDLE);
  controlP5 = new ControlP5(this);
  
  
  
  controlP5.addButton("Load", 0,0,0,80,32);
  controlP5.addButton("Save",0,80,0,80,32);
  eliminar=controlP5.addButton("Delete",0,160,0,80,32);
  modificar=controlP5.addButton("Move",0,240,0,80,32);
  controlP5.addButton("Undelete",0,320,0,80,32);
  //controlP5.setColorBackground(0x022a79);
  //controlP5.setColorForeground(0x022a79);
  eliminar.setSwitch(true);
  modificar.setSwitch(true);
  
  
  addMouseWheelListener(new java.awt.event.MouseWheelListener() { 
    public void mouseWheelMoved(java.awt.event.MouseWheelEvent evt) { 
    if(!creando){
      float zm=1+evt.getWheelRotation()/10.0f;
      println(evt);
      println("zoom: "+(zm));
      
      
      
      
      
      
      imgAncho2*=(zm);
      imgAlto2*=(zm);
      zoom=imgAncho2/imgAncho;
      zoomy=imgAlto2/imgAlto;
      println(zoom);
   }
    
    println(imgAlto+" "+imgAncho); 
  }}); 



}

 


public void keyPressed(){
 if(key=='d'){
  elim=true;
  helper.setText("DELETE MODE: Click any label or press DELETE key to remove it");
 }
 if(key=='m'){
  modif=true;
  helper.setText("MOVE MODE: use UP,DOWN,LEFT and RIGHT to move the red label");
 }
if(key==CODED){
  println("entro");
if(keyCode==UP){
 Etiqueta e2 = car.getEtiquetaModif();
 if(e2!=null)
 e2.mover(0,-1);
}
if(keyCode==DOWN){
 Etiqueta e2 = car.getEtiquetaModif();
 if(e2!=null)
 e2.mover(0,1);
}
if(keyCode==LEFT){
 Etiqueta e2 = car.getEtiquetaModif();
 if(e2!=null)
 e2.mover(-1,0);
}
if(keyCode==RIGHT){
 Etiqueta e2 = car.getEtiquetaModif();
 if(e2!=null)
 e2.mover(1,0);
}
}
if(key==(DELETE)){
 boolean etBol;
  if(cargado && elim ){
    etBol = car.borrarEtiqueta(slider.getNumImagenActual());}
    else{
      etBol=false;
    } 
}
}
public void keyReleased(){
 if(key=='d'){
  elim=false;
  helper.setText(MSGIDLE);
 } 
 if(key=='m'){
  modif = false;
  helper.setText(MSGIDLE);
 }
}

public void Undelete(){
 car.deshacer(slider.getNumImagenActual()); 
}

public void draw() {
  stroke(255);
  background(b);
  
  

  if(cargado) {
    //image(fondoEliminar,30,220,150,140);
    PImage img = slider.getImagenActual();
    if(imgAncho2==0){
    if(img.width > width -explorador.getAncho()){
    this.imgAncho2=width/2;
    this.imgAlto2=img.height*(width/2) / img.width;}
    else{
      this.imgAlto2= height/2;
      this.imgAncho2 = img.width*(height/2) / img.height;
    }
    
  this.imgAncho=imgAncho2;
this.imgAlto=imgAlto2;}
    
    //image(marco,(width/2)-imgAncho/2 -10,(height/2)-imgAlto/2 -10,imgAncho+20,imgAlto+20);
    image(slider.getImagenActual(),(width-imgAncho2)/2 + dragX,(height-imgAlto2)/2 +dragY,imgAncho2,imgAlto2);
    if(elim ==true ||modif ==true){
      
    car.dibujaretiquetas(slider.getNumImagenActual(),(int)imgAncho2,(int)imgAlto2,true,zoom,zoomy,dragX,dragY);}
    else{
      car.dibujaretiquetas(slider.getNumImagenActual(),(int)imgAncho2,(int)imgAlto2,false,zoom,zoomy,dragX,dragY);
    }
    
    if(cargado && modif){
     car.setEtMin(); 
     
    }

if(herActual!=null){
    
    herActual.displayEstado((int)imgAncho2,(int)imgAlto2,zoom,zoomy,dragX,dragY);
  }
   //image(opciones,100.0-10,height/2.0 -42,100.0,116.0); 
  slider.display();
  explorador.display();
  
  
  helper.display();
  
  }
  
  if(!cargado){
    textFont(font,28);
    fill(255);
    String s = "Click LOAD and select a folder with images";
    
   text(s,width/2-textWidth(s)/2,height/2);
  }
  
}
/*public void mousePressed(){
 car.imagenSiguiente();
 }*/



public void Load(int valor) {
  if(!creando){
    herActual=null;
  String folderPath = selectFolder();  // Opens file chooser
  if (folderPath == null) {
    // If a folder was not selected
    println("No folder was selected...");
  } 
  else {
    // If a folder was selected, print path to folder
    println("ruta2"+folderPath);


    car = new Cargador(folderPath+"\\");
    car.cargar(this,explorador);
    slider.cargar(car.getImagenes());
    cargado=true;
    crearMenus();
    slider.setNumImagenActual(0);
    slider.actualizar();
    
  }
  }
}
public void mouseReleased(){
 slider.moverSlider(sliderValue); 
 
}
public void mousePressed() {
   xd=mouseX;
   yd=mouseY;
   println("mouse 1 "+mouseX+" "+mouseY);
    boolean bol;
    if(!creando){
    bol = slider.mousePressed();}
    else{
      bol=false;
    }
    
    if(bol)
    car.resetMinima();
    boolean etBol;
   if(!creando&&cargado && elim && mouseX >( (width/2)-imgAncho2/2 )&& mouseX < ((width/2)+imgAncho2/2) && mouseY > ((height/2)-imgAlto2/2 )&& mouseY < ((height/2)+imgAlto2/2)){
    etBol = car.borrarEtiqueta(slider.getNumImagenActual());}
    else{
      etBol=false;
    }
     
    
     if(!bol && !etBol && cargado && !elim && explorador.mousePressed() && !modif && !creando) {
      herActual = explorador.getHerramienta();
      println(herActual);
      if(herActual!=null)
      helper.setText(herActual.getTextoHelper2());
      
      /*if(herActual!=-null) {
       
            
        
        switch(et) {
        case 1:
          controlP5.addTextfield("Ancho",50,160,100,14).setAutoClear(false);
          controlP5.addTextfield("Alto",50,190,100,14).setAutoClear(false);
          helper.setText("Etiqueta cuadrada: Haga dos clicks , uno por vertice a definir");
          break;
        case 2:
          controlP5.addTextfield("Radio",50,160,100,14).setAutoClear(false);
          helper.setText("Etiqueta redonda: Haga dos clicks, uno para definir el centro y otro para el radio");
          break;
        case 3:
          helper.setText("Etiqueta poligono: Haga click izquiero para definir un vertice y derecho para cerrar el poligono");
          break;
        }
      }*/
      



      
    }
    else if(herActual!=null && !bol && !etBol && cargado && !elim && !modif && mouseX >( (width/2)-imgAncho2/2 +dragX )&& mouseX < ((width/2)+imgAncho2/2 +dragX) && mouseY > ((height/2)-imgAlto2/2 +dragY)&& mouseY < ((height/2)+imgAlto2/2) +dragY){
      
      boolean crtmp=herActual.mousePressed((int)imgAncho2,(int)imgAlto2,zoom,zoomy,dragX,dragY);
      
      if(!crtmp && !creando ){
      creando=true;
       
      eliminar.setSwitch(false);
      modificar.setSwitch(false);
      creando=!crtmp;
      }
      else if(crtmp ){
        
        
        creando=true;
        eliminar.setSwitch(true);
        modificar.setSwitch(true);
        elim=false;
        modif=false;
        eliminar.setOff();
        modificar.setOff();
        modificar.update();
        eliminar.update();
        
        creando =false;
        println("agregando");
        println(herActual);
       car.agregarEtiqueta(slider.getNumImagenActual(),herActual.getLastEtiqueta()); 
      }
      println (creando);
    }
    
  

  
}

public void Delete(){
 if(!creando){
  elim=!elim;

 if(elim){
   helper.setText("DELETE MODE: Click any label or press DELETE key to remove it");
   if(modificar.booleanValue()){
     modificar.setOff();
     
   }

modif=false;


}
else{
  if(herActual!=null){
  helper.setText(herActual.getTextoHelper2());}
  else{
    helper.setText(MSGIDLE);
  }
  
}

 }
}
public void Move(){
 if(!creando){
  modif=!modif;
  
 
 
  if(modif){
    helper.setText("MOVE MODE: use UP,DOWN,LEFT and RIGHT to move the red label");
  if(eliminar.booleanValue()){
    eliminar.setOff();
    
  }
  
  elim=false;
  
  }
  else{
    
  if(herActual!=null){
  helper.setText(herActual.getTextoHelper2());}
  else{
    helper.setText(MSGIDLE);
  }
}
  
 }
  
}

public void Save() {
  if(!creando)
  car.guardarEtiquetas();
}

public void Ancho(String texto) {
  try {
    resAncho=Integer.parseInt(texto);
  }
  catch(Exception e) {
    resAncho=-1;
  }
}

public void Alto(String texto) {
  try {
    resAlto=Integer.parseInt(texto);
  }
  catch(Exception e) {
    resAlto=-1;
  }
}

public void Radio(String texto) {
  try {
    resRadio=Integer.parseInt(texto);
  }
  catch(Exception e) {
    resRadio=-1;
  }
}







public void crearMenus() {

  controlP5.addSlider("sliderValue",0,car.getNImagenes(),0,0,height-10,width,10);

  
}



public void mouseMoved() {
  
  
  if( explorador.mousePressed()){
   Herramienta her =explorador.getHerramienta();
  if(her!=null){
   helper.setTextVar(her.getTextoHelper1());
   helper.setVisible(true);
  }
 else{
 helper.setVisible(false);
 } 
  }
  else{
    helper.setVisible(false);
  }
}

public void mouseDragged(){
  if(mouseButton == RIGHT){
 
 dragX+= (mouseX-xd )/100;
  dragY+=(mouseY-yd)/100;}
 
}





public class Cargador {
  private ArrayList<String> imagenes;
  private String ruta;
  private int pos;
  private PImage imgAct;
  private ArrayList etiquetas;
  private String[] nombres;
  private XMLElement element;
  private XMLElement e;
  private int xmlPos;
  private int nEtiqueta=-1;
  private ArrayList<Etiqueta> deshacer;
  Etiqueta minima=null;
  Etiqueta etMin=null;
  private int xact=0;
  private int yact=0;

  public Cargador(String ruta) {
    this.ruta = ruta;
    deshacer = new ArrayList();
  }

  public void cargar(PApplet parent,Explorador explorador) {
    imagenes = new ArrayList();
    xmlPos=-1;
    boolean t = false;
    nombres = listarArchivos(ruta);
    println(nombres);
    for(int i= 0; i< nombres.length;i++) {
      
      String nombre = nombres[i];
      
      if(nombre.endsWith("xml")) {
        if(nombre.equals("tree.xml")){
        xmlPos=i;}
        else if(nombre.equals("tools.xml")){
         explorador.cargarConf(parent,this.ruta+"tools.xml"); 
         t=true;
        }
        
      }
      else if(nombre.endsWith("jpg")|| nombre.endsWith("gif") || nombre.endsWith("jpeg") || nombre.endsWith("tga") || nombre.endsWith("png")) {
        println("cargando "+nombre+" i: "+i);
        imagenes.add(ruta+nombres[i]);
      }
    }
    if(!t){
      explorador.cargarConf(parent,"tools.xml");
    }
    pos=0;
    println("acabo de cargar");
    imgAct =(PImage)loadImage((String)imagenes.toArray()[0]);
    
    etiquetas = new ArrayList();
    for(int i = 0 ; i < imagenes.size();i++) {
      etiquetas.add(new ArrayList());
      println("a\u00f1adiendo array etiquetas"+" "+i);
    }
    if(xmlPos!=-1) {
      cargarXml(nombres[xmlPos],parent);
    }
  }
  public void cargarXml(String nombre,PApplet parent) {
    element = new XMLElement(parent,ruta+nombre);

    for (int i=0; i < element.getChildCount(); i++) {
      XMLElement imagen = element.getChild(i);
      String nImagen = imagen.getAttribute("src");
      for(int j = 0; j<nombres.length;j++) {
        if(nombres[j].equals(nImagen)) {
          for(int k = 0; k<imagen.getChildCount();k++) {
            XMLElement etiqueta = imagen.getChild(k);
            println(etiqueta);
            if(etiqueta.getName().equals("Square")) {
              String n = etiqueta.getStringAttribute("name");
              int x = Integer.valueOf(etiqueta.getStringAttribute("x")); 
              int y = Integer.valueOf(etiqueta.getStringAttribute("y"));
              float ancho = Float.valueOf(etiqueta.getStringAttribute("width"));
              float alto = Float.valueOf(etiqueta.getStringAttribute("height"));
              println(x+" "+y+" "+ancho+" "+alto);
              
              agregarEtiqueta(j,new Etiqueta(x,y,ancho,alto,n));
            }
            
            if(etiqueta.getName().equals("Point")) {
              String n = etiqueta.getStringAttribute("name");
              int x = Integer.valueOf(etiqueta.getStringAttribute("x")); 
              int y = Integer.valueOf(etiqueta.getStringAttribute("y"));
              println(x+" "+y);
              agregarEtiqueta(j,new Etiqueta(x,y,n));
            }

            else if(etiqueta.getName().equals("Circle")) {
              String n = etiqueta.getStringAttribute("name");
              int x = Integer.valueOf(etiqueta.getStringAttribute("x")); 
              int y = Integer.valueOf(etiqueta.getStringAttribute("y"));
              float radio = Float.valueOf(etiqueta.getStringAttribute("radio"));
              agregarEtiqueta(j,new Etiqueta(x,y,radio,n));
            }
            else if(etiqueta.getName().equals("Poligon")){
              String n = etiqueta.getStringAttribute("name");
              ArrayList p = new ArrayList();
              for(int l = 0; l<etiqueta.getChildCount();l++){
               XMLElement pol = etiqueta.getChild(l);
                int[] punto = new int[2];
                 punto[0] = Integer.valueOf(pol.getStringAttribute("x")); 
                 punto[1] = Integer.valueOf(pol.getStringAttribute("y")); 
                 println("a\u00f1ado punto");
                 p.add(punto);
              }
              agregarEtiqueta(j,new Etiqueta(p,n,3));
            }
             else if(etiqueta.getName().equals("Pointsec")){
              String n = etiqueta.getStringAttribute("name");
              ArrayList p = new ArrayList();
              for(int l = 0; l<etiqueta.getChildCount();l++){
               XMLElement pol = etiqueta.getChild(l);
                int[] punto = new int[2];
                 punto[0] = Integer.valueOf(pol.getStringAttribute("x")); 
                 punto[1] = Integer.valueOf(pol.getStringAttribute("y")); 
                 p.add(punto);
              }
              agregarEtiqueta(j,new Etiqueta(p,n,5));
            }
          }
        }
      }
    }
  }



public int getNImagenes(){
 return imagenes.size(); 
}

  public String[] listarArchivos(String dir) {
    File file = new File(dir);
    if(file.isDirectory()) {
      String names[] = file.list();
      return names;
    }
    else {
      return null;
    }
  }
  public Etiqueta getUltimaEtiqueta(int imagenActual){
    println(nEtiqueta);
    ArrayList et = (ArrayList)etiquetas.get(imagenActual);
    println(nEtiqueta);
    return (Etiqueta)et.get(nEtiqueta-1);
    
  }
  public void agregarEtiqueta(int nImagen,Etiqueta etiqueta) {
    
    ArrayList e = (ArrayList)etiquetas.get(nImagen);
    
    e.add(etiqueta);
    nEtiqueta++;
  }
  public void resetMinima(){
    minima=null;
  }
  
  public void dibujaretiquetas(int imagenActual,int offsetx,int offsety,boolean elim,float zoom,float zoomy,float dragX,float dragY) {
    nEtiqueta=0;
    
    
    float distmin=1000;
    ArrayList e = (ArrayList)etiquetas.get(imagenActual);
    Iterator i = e.iterator();
    while(i.hasNext()) {
      Etiqueta et = (Etiqueta) i.next();
      et.display(offsetx,offsety,false,zoom,zoomy,dragX,dragY);
      
       if(xact!=mouseX && yact!=mouseY){ 
      if(distmin > et.getMinDist((int)offsetx,(int)offsety,zoom,zoomy,dragX,dragY)){
        distmin=et.getMinDist((int)offsetx,(int)offsety,zoom,zoomy,dragX,dragY);
        minima = et;
       
      }}
      nEtiqueta++;
    }
    if(xact!=mouseX && yact!=mouseY){
      xact=mouseX;
      yact=mouseY;
    }
    
    if(elim & minima !=null){
     minima.display( offsetx,offsety,true,zoom,zoomy,dragX,dragY);
    }
    
  }
  public void deshacer(int imagenActual){
    
    if(deshacer.size()!=0){
    ArrayList e = (ArrayList)etiquetas.get(imagenActual);
    Etiqueta et = deshacer.get(deshacer.size()-1);
    e.add(et);
    deshacer.remove(et);
    
    }
  }
  public boolean pressEtiquetas(int imagenActual,int offsetx,int offsety,float zoom,float dragX,float dragY) {
    ArrayList e = (ArrayList)etiquetas.get(imagenActual);
    Iterator i = e.iterator();
    while(i.hasNext()) {
      Etiqueta et = (Etiqueta) i.next();
      if(et.isPressed(offsetx,offsety,zoom,dragX,dragY)){
       e.remove(et);
       deshacer.add(et);
      return true ;
      }
    }
    return false;
  }

  public ArrayList<String> getImagenes() {
    return imagenes;
  }

  public void guardarEtiquetas() {
    PrintWriter output = createWriter(ruta+"tree.xml");
    output.println("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>");

    Iterator i = etiquetas.iterator();
    int contador=0;
    // e = new proxml.XMLElement("Imagenes");
    output.println("<Images>");
    while(i.hasNext()) {
      ArrayList et = (ArrayList)i.next();
      Iterator i2 = et.iterator(); 
      output.println("\t <img src=\""+nombres[contador]+"\">");
      //proxml.XMLElement img = new proxml.XMLElement("img");

      //img.addAttribute("src",nombres[contador]);
      //e.addChild(img);
      contador++; 

      while(i2.hasNext()) {
        Etiqueta etiqueta = (Etiqueta)i2.next();
        etiqueta.agregarTree(output);
      }
      output.println("\t</img>");
    }
    output.println("</Images>");

    // xmlIO.saveElement(e,ruta+"tree.xml");
    output.flush();
    output.close();
  }
  
  public int getNumEtiquetas(){
    return nEtiqueta;
  }
  public int agregarEtiquetasMenu(ListBox l,int imagenActual){
    int numEt=0;
    
    ArrayList et = (ArrayList)etiquetas.get(imagenActual);
    Iterator i = et.iterator();
    while(i.hasNext()){
      Etiqueta e = (Etiqueta) i.next();
      println("Label: "+e);
      l.addItem(e.getNombre(),numEt);
      println("agrego el numero de etiqueta "+numEt);
      numEt++;
    }
    println("label: "+numEt);
    nEtiqueta = numEt-1;
    return numEt;
  }
  
  public boolean borrarEtiqueta(int imagenActual){
    ArrayList a = (ArrayList) etiquetas.get(imagenActual);
    if(minima!=null){
      
     a.remove(minima);
     
     deshacer.add(minima);
     println("minima: "+minima);
    minima=null; 
    return true;
    }
    return false;
    /*if(a.size() > 1){
    for(int i = numero ;i < a.size()-1;i++){
    a.set(i,a.get(i+1));
    
    }
    
     a.set(a.size()-2,a.get(a.size()-1));
     a.remove(a.size()-1);
     a.trimToSize();
     println("llego");
    }*/
    
  }
  
  public void setEtMin(){
   etMin = minima; 
   println(etMin);
  }
  
  public Etiqueta getEtiquetaModif(){
    
    if(etMin!=null){
      println(etMin);
      return etMin;}
      return null;
  }
}

public class Circulo extends Herramienta{
  
  private int resRadio=-1;
  private int estado = 0;
  
  
  
  public Circulo(int posicionx,int posiciony,int altoherramienta,int anchoherramienta,String nombre){
   this.posicionx=posicionx;
   this.posiciony=posiciony;
   this.anchoherramienta = anchoherramienta;
   this.altoherramienta = altoherramienta;
   this.nombre=nombre;
   
  }
  
  public void setRadio(int resRadio){
    this.resRadio = resRadio;
  }
  
  
  public boolean mousePressed(int offsetx,int offsety,float zoom,float zoomy,float dragX,float dragY){
   if(mouseButton == LEFT){
    
    switch(estado){
    case 0:
      x=(int)((((mouseX-dragX) -((width-offsetx)/2.0f))/zoom));
      y=(int)((((mouseY-dragY) -((height-offsety)/2.0f))/zoomy));
      println("dibujo");
      estado++;
      return false;
      case 1:
      int x2 =(int)((((mouseX-dragX)-(width-offsetx)/2)/zoom));
      int y2 =(int)((((mouseY-dragY)-(height-offsety)/2)/zoomy)); 
      int radio = resRadio!= -1? resRadio:abs((int)sqrt(pow((int)(x2-x),2)+pow((int)(y2-y),2)));
      lastEtiqueta = new Etiqueta(x,y,radio,nombre);
      estado=0;
      return true;
      
   } 
   return false;
  }
  return false;
  }
  
  
  
  
    public String getTextoHelper1(){
     StringBuffer s = new StringBuffer();
     s.append(nombre+" label, circle");
     if(resRadio != -1){
     s.append(" width allways "+resRadio+" pixels of radi");}
         
     return s.toString();
 }
 
 
 
 public String getTextoHelper2(){
 return "CIRCLE MODE: Make two clicks to define the label, one for the coordinates and one for the proporcions";
}


public void displayEstado(int offsetx,int offsety,float zoom,float zoomy,float dragX,float dragY){
    
   if(estado==1){
     noFill();
     int x2 =(int)((((mouseX-dragX)-(width-offsetx)/2)/zoom));
      int y2 =(int)((((mouseY-dragY)-(height-offsety)/2)/zoomy)); 
      int radio = resRadio!= -1? resRadio:abs((int)sqrt(pow((int)(x2-x),2)+pow((int)(y2-y),2)));
      
    ellipse(((x)*zoom+dragX)+((width-offsetx)/2),((y)*zoomy+dragY)+((height-offsety)/2),radio*2*zoom,radio*2*zoomy);
    
    //line(x+((width-offsetx)/2),y+(height-offsety)/2,(x+((width-offsetx)/2))+radio,y+((height-offsety)/2));
    //text(String.valueOf(radio),(x+((width-offsetx)/2))+radio/2,y+((height-offsety)/2));
   } 
  }
  
}
public class Cuadrado extends Herramienta{
  
  private int resX=-1;
  private int resY=-1;
  private int estado = 0;
  
  
  
  public Cuadrado(int posicionx,int posiciony,int altoherramienta,int anchoherramienta,String nombre){
   this.posicionx=posicionx;
   this.posiciony=posiciony;
   this.anchoherramienta = anchoherramienta;
   this.altoherramienta = altoherramienta;
   this.nombre=nombre;
   
  }
  
  public void setResX(int resX){
    this.resX = resX;
  }
  public void setResY(int resY){
    this.resY = resY;
  }
  
  public boolean mousePressed(int offsetx,int offsety,float zoom,float zoomy,float dragX,float dragY){
   if(mouseButton == LEFT){
    
    switch(estado){
    case 0:
      
      x=(int)((((mouseX-dragX) -((width-offsetx)/2.0f))/zoom));
      y=(int)((((mouseY-dragY) -((height-offsety)/2.0f))/zoomy));
      estado++;
      return false;
      case 1:
      int x2 = resX!=-1?resX:(int)((((mouseX-dragX-(width-offsetx)/2.0f)/zoom))-x);
      int y2 = resY!=-1?resY:(int)((((mouseY-dragY-(height-offsety)/2.0f)/zoomy))-y);
      lastEtiqueta = new Etiqueta(x,y,x2,y2,nombre);
      estado=0;
      return true;
      
   } 
   return false;
  }
return false;}
  
  
  public void displayEstado(int offsetx,int offsety,float zoom,float zoomy,float dragX,float dragY){
   
   if(estado==1){
     noFill();
      int x2 = resX!=-1?resX:(int)((((mouseX-dragX-(width-offsetx)/2.0f)/zoom))-x);
      int y2 = resY!=-1?resY:(int)((((mouseY-dragY-(height-offsety)/2.0f)/zoomy))-y);
    rect((x*zoom)+((width-offsetx)/2)+dragX,(y*zoomy)+((height-offsety)/2)+dragY,x2*zoom,y2*zoomy);
    //text(String.valueOf(x2),(x+((width-offsetx)/2))+((mouseX-(width-offsetx)/2)-x)/2,y+((height-offsety)/2));
    //text(String.valueOf(y2),(x+((width-offsetx)/2)),y+((height-offsety)/2)+((mouseY-(height-offsety)/2)-y)/2);
   } 
  }
  
   public String getTextoHelper1(){
     StringBuffer s = new StringBuffer();
     s.append(nombre+" label, square");
     if(resX != -1 && resY==-1){
     s.append(" width allways "+resX+" pixels of width");}
     else if(resY!=-1 & resX==-1){
     s.append(" width allways "+resY+" pixels of height");}
     else if(resX!=-1&&resY!=-1){
     s.append(" width allways "+resX+" x "+resY+" pixels"); }    
     return s.toString();
 }
 
 
 
 public String getTextoHelper2(){
 return "SQUARE MODE: Make two clicks to define the label, one for the coordinates and one for the proporcions";
}

    
  
}
public class Etiqueta {
  private int  x1,y1;
  private float ancho,alto;
  private float radio;
  private int tipo;
  private ArrayList puntos;
  private String nombre;
  private int offsetantx=0;
  private int offsetanty=0;

  public Etiqueta(int x1,int y1,float ancho,float alto,String nombre) {
    this.x1=x1;
    this.y1=y1;
    this.ancho = ancho;
    this.alto = alto;
    this.tipo = 1;
    this.nombre = nombre;
  }

  public Etiqueta(int x1,int y1,String nombre) {
    this.x1=x1;
    this.y1=y1;
    this.tipo = 4;
    this.nombre = nombre;
  }


  public Etiqueta(int x1,int y1, float radio,String nombre) {
    this.x1=x1;
    this.y1=y1;
    this.radio=radio;
    this.tipo=2;
    this.nombre = nombre;
  }
  public Etiqueta(ArrayList puntos,String nombre,int tipo) {
    this.puntos = puntos;
    this.tipo=tipo;
    this.nombre = nombre;
  }

  public void setNombre(String nombre) {
    this.nombre = nombre;
  }

  public void mover(int x, int y) {
    if(tipo ==1 || tipo == 2 || tipo ==4) {
      this.x1+=x;
      this.y1+=y;
    }
    else if( tipo == 3 ) {

      Iterator i = puntos.iterator();
      int[] punto;
      while(i.hasNext()) {
        punto = (int[]) i.next();
        punto[0]+=x;
        punto[1]+=y;
      }
    }
  }

  public boolean isPressed(int offsetx,int offsety,float zoom,float dragX,float dragY) {
    int posx,posy;
    switch(tipo) {
    case 1:
      posx = x1+(width -offsetx)/2 ;
      posy = y1+(height -offsety)/2;
      if(mouseX > posx && mouseX < posx + ancho && mouseY > posy && mouseY < posy+alto) {
        return true;
      }


      break;
    case 2:
      posx = x1+(width -offsetx)/2 ;
      posy = y1+(height -offsety)/2 ;
      if(mouseX > posx-radio && mouseX < posx + radio  && mouseY > posy-radio && mouseY < posy+radio) {
        return true;
      }

      break;
    }
    return false;
  }

  public void display(int offsetx,int offsety,boolean elim,float zoom,float zoomy,float dragX,float dragY) {
    noFill();
    stroke(255);
    int posx,posy;
    int x1=0;
    int x2=0;
    int y1=0;
    int y2=0;
    float px=0;
    float py=0;
    
      Iterator i;
    switch(tipo) {
      
    case 1:
    px= (this.x1) * zoom;
    py = (this.y1) * zoomy;
    float pw = ancho * zoom;
    float ph = alto * zoomy;
    
      posx = (int)((px+(width -offsetx)/2));
      posy = (int)((py+(height -offsety)/2));
      if(elim) {
        stroke(255,0,0);
      }
      rect(posx+dragX ,posy+dragY,pw,ph);
      break;
    case 2:
    
       px = (this.x1) * zoom;
       py = (this.y1) * zoomy;
      float pr = this.radio * zoom;
      float pr2 = this.radio  * zoomy;
      posx = (int)(px+(width -offsetx)/2);
      posy = (int)(py+(height -offsety)/2);
      if(elim) {
        stroke(255,0,0);
        elim=!elim;
      }
      ellipse(posx+dragX,posy+dragY,pr*2,pr2*2);
      break;
    case 3:
      if(elim) {
        stroke(255,0,0);
      }
       i = puntos.iterator();
      
      int[] p = (int[]) i.next();
      x1=(int)((p[0])*zoom);
      y1=(int)((p[1])*zoomy);
      while(i.hasNext()) {

        p = (int[]) i.next();
         x2=(int)((p[0])*zoom);
      y2=(int)((p[1])*zoomy);
        
        line(x1+(width-offsetx)/2+dragX ,y1+(height-offsety)/2+dragY ,x2+(width-offsetx)/2+dragX ,y2+(height-offsety)/2+dragY );
        x1=x2;
        y1=y2;
      }
      p =(int[]) puntos.get(0);
      x2=(int)((p[0])*zoom);
      y2=(int)((p[1])*zoomy);
      line(x1+(width-offsetx)/2+dragX  ,y1+(height-offsety)/2+dragY ,x2+(width-offsetx)/2+dragX  ,y2+(height-offsety)/2+dragY  );
      break;

    case 4:
      if(elim) {
        fill(255,0,0);
        stroke(255,0,0);
      }
      else {
        fill(255);
      }
      px = (this.x1)*zoom;
      py = (this.y1)*zoomy;
      rect(px+(width-offsetx)/2+dragX ,py+(height-offsety)/2+dragY,1,1);
      break;
      
      
      case 5:
      if(elim) {
        stroke(255,0,0);
        
      }
      i = puntos.iterator();
      
      int[] p2;
      
      while(i.hasNext()) {

        p2 = (int[]) i.next();
        x2=(int)((p2[0])*zoom);
        y2=(int)((p2[1])*zoomy);
        rect(x2+(width-offsetx)/2+dragX ,y2+(height-offsety)/2+dragY,1,1);
        
      }
     
      break;
    }
  }

  public int getX() {
    return x1;
  }
  public int getY() {
    return y1;
  }
  public float getRadio() {
    return radio;
  }
  public float getAncho() {
    return ancho;
  }
  public float getAlto() {
    return alto;
  }

  public float getMinDist(int offsetx,int offsety,float zoom,float zoomy,float dragX,float dragY) {
    float dista =0;
    switch(tipo) {

    case 1:
      
      dista = abs(((((mouseX-dragX)- (width-offsetx)/2))/zoom)-this.x1);
      dista = abs(((((mouseX-dragX)- (width-offsetx)/2))/zoom)-(this.x1+this.ancho))<dista?abs(((((mouseX-dragX)- (width-offsetx)/2))/zoom)-(this.x1+this.ancho)):dista;
      dista = abs(((((mouseY-dragY)- (height-offsety)/2))/zoomy)-this.y1)<dista?abs(((((mouseY-dragY)- (height-offsety)/2))/zoomy)-this.y1):dista;
      dista = abs(((((mouseY-dragY)- (height-offsety)/2))/zoomy)-(this.y1+this.alto))<dista?abs(((((mouseY-dragY)- (height-offsety)/2))/zoomy)-(this.y1+this.alto)):dista;
      return dista;

    case 2:
      int x2 = (int)((((mouseX-dragX) -((width-offsetx)/2)))/zoom);
      int y2 = (int)((((mouseY-dragY) -((height-offsety)/2)))/zoomy);
      int rad = (int)(sqrt(pow((int)(x2-x1),2)+pow((int)(y2-y1),2)));

      return abs(radio-rad);

    case 3:

      Iterator i = puntos.iterator();
      int[] punto = (int[]) i.next();
      int[] punto2 = (int[]) i.next();
      int[] primerPunto = punto;

      float m=0;
      float b=0;
      if(punto[0] - punto2[0] == 0f) {
        //Vertical
        dista = abs((((mouseX-dragX)- (width-offsetx)/2)/zoom)-punto[0]);
      }
      else {
        m = (float)(punto2[1]-punto[1])/(punto2[0]-punto[0]);

        b = (float)punto[1] -1*m*punto[0];
        if(m==0f) {
          //Horizontal
          dista=abs(((((mouseY-dragY)- (height-offsety)/2)/zoomy)-punto[1]));
        }
        else {

          dista = abs((m*((((mouseX-dragX)-(width-offsetx)/2))/zoomy))-((((mouseY-dragY)-(height-offsety)/2))/zoomy)+b);
          dista /=sqrt(pow(m,2)+1);
        }
      }

      float dista2=100000000;
      while(i.hasNext()) {


        punto = punto2;
        punto2 = (int[]) i.next();


        if(punto[0] - punto2[0] == 0f) {
          //Vertical
          dista2= abs(((((mouseX-dragX)- (width-offsetx)/2))/zoom)-punto[0]);

          dista= dista2<dista?dista2:dista;
        }
        else {

          m =(float) (punto2[1]-punto[1])/(punto2[0]-punto[0]);
          b = (float)punto[1] -1*m*punto[0];

          if(m==0f) {
            //Horizontal
            dista2=abs(((((mouseY-dragY)- (height-offsety)/2))/zoomy)-punto[1]);
            dista= dista2<dista?dista2:dista;
          }
          else {

            dista2 = abs((m*((((mouseX-dragX)-(width-offsetx)/2))/zoom))-((((mouseY-dragY)-(height-offsety)/2))/zoomy)+b);
            dista2 /=sqrt(pow(m,2)+1);
            dista= dista2<dista?dista2:dista;
          }
        }
      }

      punto = primerPunto;

      if(punto[0] - punto2[0] == 0f) {
        //Vertical
        dista2= abs(((((mouseX-dragX)- (width-offsetx)/2))/zoom)-punto[0]);

        dista= dista2<dista?dista2:dista;
      }
      else {

        m =(float) (punto2[1]-punto[1])/(punto2[0]-punto[0]);
        b = (float)punto[1] -1*m*punto[0];

        if(m==0f) {
          //Horizontal
          dista2=abs(((((mouseY-dragY)- (height-offsety)/2))/zoomy)-punto[1]);
          dista= dista2<dista?dista2:dista;
        }
        else {

          dista2 = abs((m*((((mouseX-dragX)-(width-offsetx)/2))/zoom))-((((mouseY-dragY)-(height-offsety)/2))/zoomy+b));
          dista2 /=sqrt(pow(m,2)+1);
          dista= dista2<dista?dista2:dista;
        }
      }

      return dista;

    case 4:
      return sqrt(pow(((((mouseX-dragX)-(width-offsetx)/2))/zoom)-x1,2)+pow(((((mouseY-dragY)-(height-offsety)/2))/zoomy)-y1,2));
      
      case 5:
      
      i = puntos.iterator();
      int[] p = (int[])i.next();
      float dist = sqrt(pow(((((mouseX-dragX)-(width-offsetx)/2))/zoom)-p[0],2)+pow(((((mouseY-dragY)-(height-offsety)/2))/zoomy)-p[1],2));
      
      while(i.hasNext()){
       p=(int[])i.next();
       float distmp =  sqrt(pow(((((mouseX-dragX)-(width-offsetx)/2))/zoom)-p[0],2)+pow(((((mouseY-dragY)-(height-offsety)/2))/zoomy)-p[1],2));
       dist = distmp < dist? distmp:dist;
      }
      return dist;
      
    }
    
    return 10000;
  }

  public void agregarTree(PrintWriter output) {

    switch(tipo) {
    case 1:

      output.print("\t\t<Square ");
      output.print("name=\""+this.nombre+"\" ");
      output.print("x=\""+this.x1+"\" ");
      output.print("y=\""+this.y1+"\" ");
      output.print("height=\""+this.alto+"\" ");
      output.println("width=\""+this.ancho+"\" />");
      println(x1+" "+y1+" "+ancho+" "+alto);

      break;
    case 2:

      output.print("\t\t<Circle ");
      output.print("name=\""+this.nombre+"\" ");
      output.print("x=\""+this.x1+"\" ");
      output.print("y=\""+this.y1+"\" ");
      output.println("radio=\""+this.radio+"\" />");


      break;
    case 3:
      output.println("\t\t<Poligon name=\""+this.nombre+"\">");
      Iterator i = puntos.iterator();
      while(i.hasNext()) {
        int[] p = (int[]) i.next();
        output.print("\t\t\t<Line x=\""+p[0]);
        output.println("\" y=\""+p[1]+"\" />");
      }
      output.println("\t\t</Poligon>");
      break;

    case 4:
      output.print("\t\t<Point ");
      output.print("name=\""+this.nombre+"\" ");
      output.print("x=\""+this.x1+"\" ");
      output.println("y=\""+this.y1+"\" />");
      break;
      
      case 5:
      output.println("\t\t<Pointsec name=\""+this.nombre+"\">");
       i = puntos.iterator();
      while(i.hasNext()) {
        int[] p = (int[]) i.next();
        output.print("\t\t\t<Point x=\""+p[0]);
        output.println("\" y=\""+p[1]+"\" />");
      }
      output.println("\t\t</Pointsec>");
      break;
    }
  }

  public String getNombre() {
    return this.nombre;
  }
}

public class Explorador {

  private int ancho, alto;
  private int numeroEtiquetas;
  private int separacionx,separaciony;
  private int posicion;
  private float altoImagen,anchoImagen;
  private ArrayList etiquetas;
  private PImage bg;


  public Explorador(int alto) {
    this.alto = height-alto;
    this.ancho = 100;
    this.separacionx = 20;
    this.separaciony=10;
    this.posicion = 0;
    this.numeroEtiquetas = 5;
    this.etiquetas = new ArrayList();

    this.anchoImagen = this.ancho - 2*separacionx;
    println(anchoImagen);
    //this.altoImagen =( height-(this.separaciony*(numeroEtiquetas +1 ) ))/numeroEtiquetas;
   
   bg=loadImage("explorador.png");

   
  }

  public void display() {

     image(bg,width-ancho,0,ancho,alto);
    Iterator i = etiquetas.iterator();
    while(i.hasNext()){
     Herramienta her = (Herramienta)i.next(); 
     her.display();
     
    }

    

    fill(0,255,0);
   
  }

  public boolean mousePressed(){
   if(mouseX > width-ancho && mouseX < width && mouseY>0 && mouseY < alto){
    return true;}
    else{
      return false;
    }
  }

  public Herramienta getHerramienta() {
    Iterator i = etiquetas.iterator();
    
    while(i.hasNext()){
     Herramienta her = (Herramienta) i.next();
      if(her.isPressed()){
      return her;
      }
    }
    return null;
  }
  
  public int getAncho(){
   return this.ancho; 
  }
  
  public void cargarConf(PApplet parent,String fichero){
    XMLElement element = new XMLElement(parent,fichero);
    numeroEtiquetas = element.getChildCount();
    println("numero herramientas: "+numeroEtiquetas);
    
    this.altoImagen =( alto-(this.separaciony*(numeroEtiquetas +1 ) ))/numeroEtiquetas;
    this.altoImagen = this.altoImagen>height/6?height/6:this.altoImagen;
   
    
    for(int i=0;i<numeroEtiquetas;i++){
     XMLElement tool = element.getChild(i);
     
     
     
     if(tool.getName().equals("square")){
       int an=-1;
     int al=-1;
     String nombre="default";
       Cuadrado her=null;
     if(tool.hasAttribute("name")){
        nombre = tool.getStringAttribute("name");
       her =  new Cuadrado(width-ancho+separacionx,(int)(separaciony + (i*altoImagen)+(i*separaciony)),(int)altoImagen,(int)this.anchoImagen,nombre);
       println(her);
     }
     
     
      if(tool.hasAttribute("width")){
        an = Integer.valueOf(tool.getStringAttribute("width"));
        her.setResX(an);
      }
      if(tool.hasAttribute("height")){
        al = Integer.valueOf(tool.getStringAttribute("height"));
        her.setResY(al);
      }
    etiquetas.add(her);
  }
  else if(tool.getName().equals("circle")){
    Circulo her = null;
    String nombre = "default";
    int radio=-1;
    
     if(tool.hasAttribute("name")){
        nombre = tool.getStringAttribute("name");
       her =  new Circulo(width-ancho+separacionx,(int)(separaciony + (i*altoImagen)+(i*separaciony)),(int)altoImagen,(int)this.anchoImagen,nombre);
       println(her);
     }
     if(tool.hasAttribute("radio")){
       radio = Integer.valueOf(tool.getStringAttribute("radio"));
       her.setRadio(radio);
     }
     etiquetas.add(her);
  }
  
  else if(tool.getName().equals("poligon")){
    Poligono her = null;
    String nombre = "default";
    int lados=-1;
    
     if(tool.hasAttribute("name")){
        nombre = tool.getStringAttribute("name");
       her =  new Poligono(width-ancho+separacionx,(int)(separaciony + (i*altoImagen)+(i*separaciony)),(int)altoImagen,(int)this.anchoImagen,nombre);
       println(her);
     }
     if(tool.hasAttribute("sides")){
       lados = Integer.valueOf(tool.getStringAttribute("sides"));
       her.setResNLados(lados);
     }
     etiquetas.add(her);
  }
  
  else if(tool.getName().equals("pointsec")){
    Secuencia her = null;
    String nombre = "default";
    int lados=-1;
    
    
     if(tool.hasAttribute("name")){
        nombre = tool.getStringAttribute("name");
       her =  new Secuencia(width-ancho+separacionx,(int)(separaciony + (i*altoImagen)+(i*separaciony)),(int)altoImagen,(int)this.anchoImagen,nombre);
       println(her);
     }
     if(tool.hasAttribute("points")){
       lados = Integer.valueOf(tool.getStringAttribute("points"));
       her.setResNLados(lados);
     }
     etiquetas.add(her);
  }
  
  else if(tool.getName().equals("point")){
    Punto her = null;
    String nombre = "default";
    
    
     if(tool.hasAttribute("name")){
        nombre = tool.getStringAttribute("name");
       her =  new Punto(width-ancho+separacionx,(int)(separaciony + (i*altoImagen)+(i*separaciony)),(int)altoImagen,(int)this.anchoImagen,nombre);
       println(her);
     }
     
     etiquetas.add(her);
  }
      
      
      
     
  }
  
  
}
}

public class Helper{
 private int anchoVar;
 private int altoVar;
 private int posXVar;
 private int posYVar;
 private String textVar;
 private boolean visible;
 private int direccion;
 
 private int anchoFix;
 private int altoFix;
 private int posXFix;
 private int posYFix;
 private String textFix;
 
 private PFont font;
 private final int FONTSIZE=10;
 private PImage back;
 
 public Helper(int offset,int ancho,int offsety){
   font = loadFont("ComicSansMS-10.vlw");
   textFont(font,FONTSIZE);
  
   
  this.posXFix=offset;
  this.posYFix = height-offsety-15;
  this.anchoFix = width-ancho-offset;
  this.altoFix = FONTSIZE; 
  this.textFix = "";
  
  this.posXVar=-1;
  this.posYVar=-1;
  this.anchoVar=200;
  this.altoVar=FONTSIZE;
  this.textVar="";
  this.visible=false;
  this.direccion=1;
  
  back = loadImage("helper.png");
  }
 
 public void display(){
  //fill(255);
  //rect(posXFix,posYFix,anchoFix,altoFix); 
  image(back,0,posYFix-5,width,20);
  fill(255);
  text(textFix,posXFix,posYFix+altoFix);
  
  if(visible){
   if(mouseX+anchoVar > width){
    direccion=-1;  
  }
   else if(mouseX-anchoVar < 0){
     direccion=1;
   }
   fill(255);
  //rect(mouseX,mouseY,anchoVar*direccion,altoVar);
  
 
 char[] tmp = textVar.toCharArray();
 float ancho=0;
 for(int i=0;i<tmp.length;i++){
   ancho+=font.width(tmp[i])*10;
 }
 println(ancho);
 image(back,mouseX,mouseY+2,(ancho*direccion)+(20*direccion),altoVar);
 if(direccion==1){
text(textVar,mouseX,mouseY+altoVar); }
else{
  text(textVar,mouseX-ancho-10,mouseY+altoVar);
}
  }
  
 }
 
 public void setText(String t){
   this.textFix = t;
 }
 public void setTextVar(String t){
   this.textVar=t;
 }
 
 public void setVisible(boolean bol){
   this.visible=bol;
 }
}
public class Herramienta{
  
 public int x,y;
 public Etiqueta lastEtiqueta;
 public int posicionx,posiciony,altoherramienta,anchoherramienta;
 public String nombre;
 public PFont fuente;
 public PImage bg;

 
  
  public Herramienta(){
   fuente = loadFont("ComicSansMS-10.vlw");
   textFont(fuente,10); 
   bg = loadImage("boton.png");
  }
 
 public void display(){
  image(bg,posicionx,posiciony,anchoherramienta,altoherramienta);
  
 // rect(posicionx,posiciony,anchoherramienta,altoherramienta);
  fill(0);
  text(nombre,posicionx+anchoherramienta/4,posiciony+altoherramienta/2);
   
 } 
 public Etiqueta getLastEtiqueta(){
   return lastEtiqueta;
 }
 public boolean isPressed(){
   if(mouseX > posicionx && mouseX < posicionx+anchoherramienta && mouseY > posiciony && mouseY<posiciony+altoherramienta){
    
   return true;
   }
   
   return false;
 }
 
 public void displayEstado(int offsetx,int offsety,float zoom,float zoomy,float dragX,float dragY){
   
 }
 
 public boolean mousePressed(int offsetx,int offsety,float zoom,float zoomy,float dragX,float dragY){
   return false;
 }
 
 public String toString(){
  return("Etiqueta con posicion x: "+posicionx+" posicion y: "+posiciony+" ancho: "+anchoherramienta+" alto: "+altoherramienta); 
 }
 
 public String getTextoHelper1(){
   return "";
 }
 
 public String getTextoHelper2(){
 return "";
}

 
}
public class Poligono extends Herramienta{
  
  private int resNLados=-1;
  private int estado = 0;
  private ArrayList puntos;
  private int lados=0;
  
  
  
  public Poligono(int posicionx,int posiciony,int altoherramienta,int anchoherramienta,String nombre){
   this.posicionx=posicionx;
   this.posiciony=posiciony;
   this.anchoherramienta = anchoherramienta;
   this.altoherramienta = altoherramienta;
   this.nombre=nombre;
   this.puntos = new ArrayList();
  }
  
  public void setResNLados(int res){
    this.resNLados = res;
  }
  
  
  public boolean mousePressed(int offsetx,int offsety,float zoom,float zoomy,float dragX,float dragY){
   
    int[] punto = new int[2];
    switch(estado){
    case 0:
    if(mouseButton == LEFT){
      puntos=new ArrayList();
      punto[0]=(int)((((mouseX-dragX) -((width-offsetx)/2))/zoom));
        punto[1]=(int)(((mouseY-dragY) -((height-offsety)/2))/zoomy);
      puntos.add(punto);
      estado++;
      lados++;
      return false;}
      case 1:
      if(mouseButton==LEFT){
        if(lados<resNLados-1 || resNLados ==-1){
        punto[0]=(int)((((mouseX-dragX) -((width-offsetx)/2))/zoom));
        punto[1]=(int)((((mouseY-dragY) -((height-offsety)/2))/zoomy));
        puntos.add(punto);
        lados++;
        return false;}
        else{
         punto[0]=(int)((((mouseX-dragX) -((width-offsetx)/2))/zoom));
        punto[1]=(int)((((mouseY-dragY) -((height-offsety)/2))/zoomy));
        puntos.add(punto);
        lastEtiqueta = new Etiqueta(puntos,nombre,3);
        estado=0;
        println("acabo");
        lados=0;
        return true;
        }
      }
      else if (mouseButton==RIGHT && resNLados==-1 && lados > 1){
        //punto[0]=mouseX -((width-offsetx)/2);
        //punto[1]=mouseY -((height-offsety)/2);
        //puntos.add(punto);
        lastEtiqueta = new Etiqueta(puntos,nombre,3);
        estado=0;
        lados=0;
        println("acabo");
        return true;
        
        
      }
      
      
      
   } 
   return false;
  }
  
  
  public void displayEstado(int offsetx,int offsety,float zoom,float zoomy,float dragX,float dragY){
   if(estado==1){
     Iterator i = puntos.iterator();
     int[] puntoAnt = (int[])i.next();
     
     while(i.hasNext()){
      int[] punto = (int[]) i.next();
      
      line(puntoAnt[0]*zoom+((width-offsetx)/2)+dragX,puntoAnt[1]*zoomy+((height-offsety)/2)+dragY,
      punto[0]*zoom+((width-offsetx)/2)+dragX,punto[1]*zoomy+((height-offsety)/2)+dragY);
      
      
      puntoAnt=punto;
      
     }
     int dist =(int) sqrt(pow((puntoAnt[0]+((width-offsetx)/2))-mouseX,2)+pow((puntoAnt[1]+((height-offsety)/2))-mouseY,2));
     line(puntoAnt[0]*zoom+((width-offsetx)/2)+dragX,puntoAnt[1]*zoomy+((height-offsety)/2)+dragY, mouseX,mouseY);
     //text(String.valueOf(dist),(puntoAnt[0]+((width-offsetx)/2)),puntoAnt[1]+((height-offsety)/2));
   } 
  }
  
  
    public String getTextoHelper1(){
     StringBuffer s = new StringBuffer();
     s.append(nombre+" label, poligon");
     if(resNLados != -1){
     s.append(" width allways "+resNLados+" sides");}
        
     return s.toString();
 }
 
 
 
 public String getTextoHelper2(){
 return "POLIGON MODE: Make right click to define the label and right click to finish it";
}
  
}
public class Secuencia extends Herramienta{
  
  private int resNLados=-1;
  private int estado = 0;
  private ArrayList puntos;
  private int lados=0;
  
  
  
  public Secuencia(int posicionx,int posiciony,int altoherramienta,int anchoherramienta,String nombre){
   this.posicionx=posicionx;
   this.posiciony=posiciony;
   this.anchoherramienta = anchoherramienta;
   this.altoherramienta = altoherramienta;
   this.nombre=nombre;
   this.puntos = new ArrayList();
  }
  
  public void setResNLados(int res){
    this.resNLados = res;
  }
  
  
  public boolean mousePressed(int offsetx,int offsety,float zoom,float zoomy,float dragX,float dragY){
  
     
     
    int[] punto = new int[2];
    switch(estado){
    case 0:
    if(mouseButton == LEFT){
      puntos=new ArrayList();
      punto[0]=(int)((((mouseX-dragX) -((width-offsetx)/2))/zoom));
      punto[1]=(int)((((mouseY-dragY) -((height-offsety)/2))/zoomy));
      puntos.add(punto);
      estado++;
      lados++;
      return false;}
      case 1:
      if(mouseButton==LEFT){
        if(lados<resNLados-1 || resNLados == -1){
        punto[0]=(int)((((mouseX-dragX) -((width-offsetx)/2))/zoom));
      punto[1]=(int)((((mouseY-dragY) -((height-offsety)/2))/zoomy));
        puntos.add(punto);
        lados++;
        return false;}
        else{
        punto[0]=(int)((((mouseX-dragX) -((width-offsetx)/2))/zoom));
      punto[1]=(int)((((mouseY-dragY) -((height-offsety)/2))/zoomy));
        puntos.add(punto);
        lastEtiqueta = new Etiqueta(puntos,nombre,5);
        estado=0;
        println("acabo");
        lados=0;
        return true;
        }
      }
      else if (mouseButton==RIGHT && resNLados==-1){
        //punto[0]=mouseX -((width-offsetx)/2);
        //punto[1]=mouseY -((height-offsety)/2);
        //puntos.add(punto);
        lastEtiqueta = new Etiqueta(puntos,nombre,5);
        estado=0;
        lados=0;
        println("acabo");
        return true;
        
        
      }
      
      
      
   } 
   return false;
  }
  
  
  public void displayEstado(int offsetx,int offsety,float zoom,float zoomy,float dragX,float dragY){
   if(estado==1){
     Iterator i = puntos.iterator();
     
     
     while(i.hasNext()){
      int[] punto = (int[]) i.next();
      
      rect(punto[0]*zoom+((width-offsetx)/2)+dragX,punto[1]*zoomy+((height-offsety)/2)+dragY,1,1);
      
      
     
      
     }
     
   } 
  }
  
  
    public String getTextoHelper1(){
     StringBuffer s = new StringBuffer();
     s.append(nombre+" label, pont secuence");
     if(resNLados != -1){
     s.append(" width allways "+resNLados+" points");}
        
     return s.toString();
 }
 
 
 
 public String getTextoHelper2(){
 return "SECUENCE MODE: Make right click to define the label and right click to finish it";
}
  
}
class Slider{
 
  ArrayList<String> imagenes;
  private int numImagenes;
  private int alto;
  private int separacionx,separaciony;
  private int posicion;
  private int imgAct;
  private float anchoImagen,altoImagen;
  private boolean cargado;
  private float desplazamiento=0;
  private PImage bg;
  private ArrayList<PImage> imagenesVisibles;
  private PImage imgActual;
  
    
  
  
 public Slider(ArrayList<String> imagenes){
   this.imagenes = imagenes;
   this.numImagenes =imagenes.size();
  println(numImagenes); //(10 > imagenes.size() ? imagenes.size():10);
   this.alto = 100;
   this.separacionx = 20;
   this.separaciony=10;
   this.posicion = 0;
   this.imgAct=0;
   this.cargado = true;
   
   
   
   
   

     
   
 }
 public Slider(){
   this.alto = 100;
   this.separacionx=20;
   this.separaciony = 10;
   this.posicion = 0;
   this.imgAct=0;
   this.cargado=false;
   bg=loadImage("slider.png");
   this.imagenesVisibles = new ArrayList();
   this.desplazamiento=0;
 }
 
 public void moverSlider(int val){
  
  println("valor: "+val);
  if(val!=desplazamiento){
    desplazamiento = val;
    actualizar();
  }
  
}
 
 public void cargar(ArrayList<String> imagenes){
   this.imagenes = imagenes;
   this.numImagenes =  (10 > imagenes.size() ? imagenes.size():10);
   this.cargado = true;
   this.imgActual=(PImage)loadImage((String)imagenes.toArray()[0]);
   
 }
 
 public void actualizar(){
   
   if(cargado){
   anchoImagen = ((width-(this.separacionx * (this.numImagenes+1)))/this.numImagenes);
   altoImagen = (alto-this.separaciony*2);
   
   imagenesVisibles.clear();
   
  
   for(int i = (int)desplazamiento; i<(desplazamiento+10<imagenes.size()?desplazamiento+10:imagenes.size()) ;i++){
   PImage img = loadImage((String)imagenes.get(i));
   img.resize((int)anchoImagen,(int)altoImagen);
   imagenesVisibles.add(img);
   
   
 
 }
  /*int nImg = (int)((mouseX)/(anchoImagen+separacionx));
   imgAct =(int) (nImg); 
   this.imgActual=imagenesVisibles.get(imgAct+desplazamiento);*/
   
 }
}
 
 public void display(){
   
   
   
   
   
   //rect(0,height-this.alto,width,height);
  
   image(bg,0,height-this.alto,width,this.alto);
   
   
   if(cargado){
   anchoImagen = ((width-(this.separacionx * (this.numImagenes+1)))/this.numImagenes);
   altoImagen = (alto-this.separaciony*2);
   
   
   for(int i = 0; i<imagenesVisibles.size();i++){
     
     
   int nImg = (int)((mouseX)/(anchoImagen+separacionx));
   
   
   
   
   if(mouseY >height - alto+separaciony && mouseY <height-separaciony && mouseX > anchoImagen*nImg + separacionx*(nImg+1) && nImg+posicion == i+posicion){
   image((PImage)imagenesVisibles.get(i),(separacionx*(i+1)+(i*anchoImagen))-20,(height-alto+separaciony)-20,anchoImagen+40,altoImagen+40);
   }
   
   
     
  else{
     image((PImage)imagenesVisibles.get(i),separacionx*(i+1)+(i*anchoImagen),height-alto+separaciony,anchoImagen,altoImagen);}
   }
   
  
   
 
 }
   
 
   
   
   }
 
public void Siguiente(int valor){
  
  if(posicion+numImagenes+1 < imagenes.size()){
    posicion++;
    println(posicion);
  }
  
}
public void Anterior(int valor){
if(posicion>=1){
  posicion--;
  println(posicion);
}
}

public boolean mousePressed(){
  if(mouseY >height - alto+separaciony && mouseY <height-separaciony){
   int nImg = (int)((mouseX)/(anchoImagen+separacionx)); 
   if(mouseX > anchoImagen*nImg + separacionx*(nImg+1)){
   imgAct =(int) (nImg+desplazamiento); 
   this.imgActual=loadImage((String)imagenes.get(imgAct));//imagenesVisibles.get(nImg);
   println("numero= "+nImg);
   return true;
   }
   return true;
  }
  return false;
}

public PImage getImagenActual(){
  return imgActual;
}
public int getNumImagenActual(){
  return (int)(imgAct);
}
public void setNumImagenActual(int num){
 imgAct=num; 
}

public int getAlto(){
  return this.alto;
}

}
public class Punto extends Herramienta{
  
  
  
  
  
  
  public Punto(int posicionx,int posiciony,int altoherramienta,int anchoherramienta,String nombre){
   this.posicionx=posicionx;
   this.posiciony=posiciony;
   this.anchoherramienta = anchoherramienta;
   this.altoherramienta = altoherramienta;
   this.nombre=nombre;
   
  }
  
 
  
  public boolean mousePressed(int offsetx,int offsety,float zoom,float zoomy,float dragX,float dragY){
   
    if(mouseButton == LEFT){
      println("drag: "+dragX+" " +dragY);
    
      x=(int)((((mouseX-dragX) -((width-offsetx)/2))/zoom));
      y=(int)((((mouseY-dragY) -((height-offsety)/2))/zoomy));
      println("mouse "+x+" "+y);
      lastEtiqueta = new Etiqueta(x,y,nombre);
      println("retorno true");
      return true;
    }
   return false;
  }
  
  public void displayEstado(int offsetx,int offsety,float zoom,float zoomy,float dragX,float dragY){
   if(estado==1){
    fill(255);
     
    rect(x*zoom+((width-offsetx)/2)+dragX*zoom,y*zoomy+((height-offsety)/2)+dragY*zoomy,1,1);
   } 
  }
  
  public String getTextoHelper1(){
     StringBuffer s = new StringBuffer();
     s.append(nombre+" label, point");
          
     return s.toString();
 }
 
 
 
 public String getTextoHelper2(){
 return "POINT MODE: Make one click to define the label";
}
 
  
}
  static public void main(String args[]) {
    PApplet.main(new String[] { "--bgcolor=#F0F0F0", "Interficie" });
  }
}
